/*

 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Day09_Ex5_wildCards;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

/**
 *
 * @author Mark
 */
public class WildCards
{

    private static int k;

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args)
    {
        /*List<String> ls = new ArrayList<String>();
        List<Object> lo = ls;
        lo.add(new Object());
        String s = ls.get(0);
         */
    	
    	//THIS IS LEGAL! BUT WE CAN'T SET ANYTHING HERE BECAUSE WE CANNOT GUARENTEE THAT ITS A SUPER OR SUB TYPE OF ?
    	Box<?> b1 = new Box<Integer>();
    	Box<?> b2 = new Box<String>();
    	b1 = b2;
    	
    	

        List<String> myList = new ArrayList<String>();
        myList.add("Mark");
        myList.add("Mark");
        myList.add("James");
        myList.add("Laura");
        myList.add("Laura");
        myList.add("Lorraine");

        printCollection(myList);
        System.out.println("");

        removeAdjacent2(myList);
        
        printCollectionGen(myList);
        System.out.println("");

        ArrayList<Integer> numArrayList = new ArrayList<Integer>();

        numArrayList.add(3);
        numArrayList.add(4);
        numArrayList.add(5);
        numArrayList.add(6);

        System.out.println("Total sum is: " + sumAll(numArrayList));
        
        Integer[] ii = {1,2,3,4,5,6,7,8};
        
        System.out.println("Count Greater than 2 is: " + countGreaterThan(ii, 2));

    }

    //method that accepts collections
    public static void printCollection(@SuppressWarnings("rawtypes") Collection c)
    {
        @SuppressWarnings("rawtypes")
		Iterator i = c.iterator();
        for (k = 0; k < c.size(); k++)
        {
            System.out.println(i.next());
        }
    }

    //Poor attempt at generics
    public static void printCollectionTrad(Collection<Object> c)
    {
        for (Object e : c)
        {
            System.out.println(e);
        }
    }

    //generic approach with unknown type
    public static void printCollectionGen(Collection<?> c)
    {
        for (Object e : c)
        {
            System.out.println(e);
        }

    }

    //generic method to remove adjacent items if they are duplicates
    public static void removeAdjacent2(Collection<?> coll)
    {
        Iterator<?> it = coll.iterator(); // Can use <?> in local variables 
        Object last = null; // Cannot use ? as a var type, use Object 
        while (it.hasNext())
        {
            Object curr = it.next();
            if (curr == last)
            {
                it.remove();
            }
            last = curr;
        }
    }

    //example method to show constraints applied to unknown type.
    public static int sumAll(Collection<? extends Number> nums)
    {
        int sum = 0;

        for (Number num : nums)
        {
            // All the Number types respond to intValue(). 
            sum += num.intValue();
        }
        return sum;
    }

    //example to show problem with applying > to objects.
    public static <T> int countGreaterThan(T[] anArray, T elem)
    {
        int count = 0;
        for (T e : anArray)
        //   if (e > elem)  // compiler error
        {
            ++count;
        }
        return count;
    }
    
    public static <T extends Comparable<T>> int countGreaterThan(T[] anArray, T elem) {
    int count = 0;
    for (T e : anArray)
        if (e.compareTo(elem) > 0)
            ++count;
    return count;
}

}
